package sample;

import io.netty.bootstrap.Bootstrap;
import io.netty.channel.*;
import io.netty.channel.group.ChannelGroup;
import io.netty.channel.group.DefaultChannelGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.codec.DelimiterBasedFrameDecoder;
import io.netty.handler.codec.Delimiters;
import io.netty.handler.codec.string.StringDecoder;
import io.netty.handler.codec.string.StringEncoder;
import io.netty.util.concurrent.GlobalEventExecutor;
import javafx.application.Platform;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.fxml.FXML;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.ListView;
import javafx.scene.control.TextField;

import java.util.Timer;
import java.util.TimerTask;

public class Controller {


    Channel channel = null;
    EventLoopGroup workerGroup;
    Bootstrap bootstrap;
    Timer timer = new Timer();
    @FXML
    private TextField send_msg;
    @FXML
    private Button send_click;
    @FXML
    private ListView<String> list_msg;
    @FXML
    private Label title_label;
    private ObservableList<String> apiList = FXCollections.observableArrayList();
    private int serverPort = 1234;
    private String serverHost = "121.37.30.8";

    public void start() throws InterruptedException {
        workerGroup = new NioEventLoopGroup();
        bootstrap = new Bootstrap();
        bootstrap.group(workerGroup).channel(NioSocketChannel.class)
                .handler(new ChannelInitializer<SocketChannel>() {

                    @Override
                    protected void initChannel(SocketChannel ch) throws Exception {
                        ChannelPipeline pipeline = ch.pipeline();

                        // On top of the SSL handler, add the text line codec.
                        pipeline.addLast(new DelimiterBasedFrameDecoder(8192, Delimiters.lineDelimiter()));
                        pipeline.addLast(new StringDecoder());
                        pipeline.addLast(new StringEncoder());

                        // and then business logic.
                        pipeline.addLast(new ChatClientHandler());
                    }
                });
        channel = bootstrap.connect(serverHost, serverPort).sync().channel();

    }

    void printPanel(String str) {
        Platform.runLater(new Runnable() {
            @Override
            public void run() {
                apiList.add(str);
                list_msg.setItems(apiList);
            }
        });
    }

    void printTitle(String str) {
        Platform.runLater(new Runnable() {
            @Override
            public void run() {
                title_label.setText(str);
            }
        });
    }

    public void send(String str) {
        try {
            if (!channel.isOpen()) {
                return;
            }
            channel.writeAndFlush(str);
            send_msg.setText("");
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    public void close() {
        try {
            if (channel != null)
                channel.close();
            System.out.println("关闭了");
        } finally {
            if (workerGroup != null)
                workerGroup.shutdownGracefully();
        }
    }

    public void init() {
        try {
            timer.schedule(new TimerTask() {
                @Override
                public void run() {
                    try {
                        if (channel == null || !channel.isOpen()) {
                            start();
                        }
                        printTitle("聊天室--在线");
                    } catch (Exception e) {
                        printTitle("聊天室--网络重新连接中");
                    }
                }
            }, 0, 3000);

        } catch (Exception e) {
            printTitle("聊天室--网络重新连接中");
        }
    }

    @FXML
    public void sendClick() {
        this.send(send_msg.getText() + "\n");
    }

    public class ChatClientHandler extends SimpleChannelInboundHandler<String> {
        private final ChannelGroup CHANNELS = new DefaultChannelGroup(GlobalEventExecutor.INSTANCE);

        @Override
        protected void channelRead0(ChannelHandlerContext ctx, String msg) throws Exception {
            printPanel(msg);
        }

        @Override
        public void channelActive(ChannelHandlerContext ctx) throws Exception {
            CHANNELS.add(ctx.channel());
        }
    }
}
